﻿#region using statements

using System;

using AeonOfStrife.Combat;
using AeonOfStrife.GUI.Layouts;
using AeonOfStrife.Misc;
using AeonOfStrife.Objects;
using AeonOfStrife.Objects.Units;

using AeonOfStrifeDatatypes.Units;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

using NGen;
using NGen.Managers.GUI;
using NGen.Managers.GameObject;
using NGen.Managers.GameState;
using NGen.Managers.Input;
using NGen.Managers.Pathfinding;

using Nuclex.Input;

#endregion

namespace AeonOfStrife.States
{
	public class GameStatePlay : GameState, IKeyboardListener, IMouseListener {
	
		#region local fields

		private readonly GUIElement m_gui = new GUILayoutPlay();

		private int m_scrollSpeed;

		#endregion

		#region IKeyboardListener Members

		public void KeyPressed(Keys p_key) {
			
			if(p_key == Keys.Left) {
				m_scrollSpeed = 10;
			}

			if(p_key == Keys.Right) {
				m_scrollSpeed = -10;
			}

			if(p_key == Keys.Space) {
				var projectile = new Projectile();
				GameEngine.GetService<IManagerGameObjects>().AddObject(projectile);
			}
		}

		public void KeyReleased(Keys p_key) {
			switch(p_key) {
				case Keys.Left:
					m_scrollSpeed = 0;
					break;
				case Keys.Right:
					m_scrollSpeed = 0;
					break;
			}
		}

		#endregion

		#region IMouseListener Members

		public void MousePressed(MouseButtons p_button) {
			Console.Write(GameEngine.GetService<IManagerInput>().GetMouseState().X + ", ");

			Console.WriteLine(GameEngine.GetService<IManagerInput>().GetMouseState().Y);

		}

		public void MouseReleased(MouseButtons p_button) {}

		public void MouseMoved(float p_x, float p_y) {
			if(p_x < 0 || p_y < 0) {
				m_scrollSpeed = 0;
				return;
			} 

			if(p_x < 200) {
				m_scrollSpeed = (int)((200f - p_x) / 15f);
			} else if(p_x > GameEngine.GameWindow.ClientBounds.Width - 200) {
				m_scrollSpeed = (int)(((GameEngine.GameWindow.ClientBounds.Width - p_x) -200f)/ 15f);
			} else {
				m_scrollSpeed = 0;
			}
		}

		public void MouseWheelScroll(float p_ticks) {}

		#endregion

		#region GameState implementation

		protected override void _Initialize() {
			GameEngine.GetService<IManagerGUI>().AddElement(m_gui);
			GameEngine.GetService<IManagerGameObjects>().AddObject(new PlayBackground());
			GameEngine.GetService<IManagerInput>().AddKeyboardListener(this);
			GameEngine.GetService<IManagerInput>().AddMouseListener(this);
			GameEngine.GameServices.AddService(typeof(IUnitManager), new UnitManager());

			var gridSize = new Point(Constants.c_PATHFINDING_X_CELL_COUNT, Constants.c_PATHFINDING_Y_CELL_COUNT);
			var pathData = new PathfindingData(gridSize, new Point(GameEngine.GameWindow.ClientBounds.Width * 3, GameEngine.GameWindow.ClientBounds.Height));
			GameEngine.GameServices.AddService(typeof(PathfindingData), pathData);
			var passableMap = new bool[gridSize.X, gridSize.Y];
			for(var x = 0; x < gridSize.X; x++) {
				for(var y = 0; y < gridSize.Y; y++) {
					passableMap[x, y] = y <= gridSize.Y/2;
				}
			}

			GameEngine.GetService<IManagerPathfinding>().SetParams(gridSize.X, gridSize.Y, 1, -1, passableMap);
			GameEngine.GetService<IManagerPathfinding>().MaintainClosedList = false;
			pathData.WorldSize = gridSize;
			pathData.CellCostMultiplier = GameEngine.GetService<IManagerPathfinding>().CellCostsMultiplier;
			for(var x = 0; x < gridSize.X; x++) {
				
				for(var y = 0; y < gridSize.Y/2; y++) {
					pathData.CellCostMultiplier[x, y] = Constants.c_PATHFINDING_MAX_VALUE;
					pathData.CellPassableMap[x, y] = true;
				}
			}

			var gameData = new GameData(new Vector2(125, 425), new Vector2(GameEngine.GameWindow.ClientBounds.Width * 3 - 125, 425));
			GameEngine.GameServices.AddService(typeof(GameData), gameData);

			GameEngine.GetService<IManagerGameObjects>().AddObject(gameData.CastleLeft);
			GameEngine.GetService<IManagerGameObjects>().AddObject(gameData.CastleRight);
			
			InitializeUnits();
		}

		protected override void _Cleanup() {
			GameEngine.GetService<IManagerGUI>().ClearGUI();
			GameEngine.GetService<IManagerInput>().RemoveKeyboardListener(this);
			GameEngine.GetService<IManagerInput>().RemoveMouseListener(this);
		}

		protected override void _OnFocusLost() {}

		protected override void _OnFocusGained() {}

		protected override void _Update(GameTime p_gameTime) {
			GameEngine.GetService<IManagerGameObjects>().TransformMatrix =
				GameEngine.GetService<IManagerGameObjects>().TransformMatrix *
				Matrix.CreateTranslation(m_scrollSpeed, 0, 0);

			GameEngine.GetService<PathfindingData>().ProcessQueue();
		}

		protected override void _Draw(GameTime p_gameTime) {}

		#endregion

		#region local methods

		private void InitializeUnits() {
			var mgr = GameEngine.GetService<IUnitManager>();
			

			mgr.AddUnitType("test", GameEngine.GameContent.Load<UnitStatsXMLReader>("Content\\test\\testUnit"));
			mgr.AddUnitType("testRanged", GameEngine.GameContent.Load<UnitStatsXMLReader>("Content\\test\\testRangedUnit"));
		}

		#endregion
	}
}